#pragma once
#include <string>
#include <vector>
#include <iostream>
#include "../mqcommom/helper.hpp"
#include "../mqcommom/msg.pb.h"
/*********************
*功能类，涉及匹配规则
* routingkey  music.pop.1  a<=x<=Z 0~9 _ . 组成
* bindingkey  music.pop.#  #.pop.*.  a<=x<=Z 0~9 _ . * # 组成
*
    根据交换机的类型进行推送
    直接--匹配routingkey和bindingkey
    主题-- music.pop  #.pop
    广播--全部匹配
*
*********************/

using namespace ns_helper;

namespace ns_rabbitmq
{
    class Router
    {
    public:
        static bool IsRoutingKeylegal(const std::string &routingkey)
        {
            if (!routingkey.size())
                return false;
            // 检查合法性
            for (auto &ch : routingkey)
            {
                if (('A' <= ch && ch<='z') ||
                   ( '0' <= ch&& ch <= '9') || ch == '_' ||
                    ch == '.')
                    continue;
                else
                    return false;
            }
            return true;
        }

        static bool IsBindingKeylegal(const std::string &bindingkey)
        {
            if (!bindingkey.size())
                return false;
            // 检查合法性
            for (auto &ch : bindingkey)
            {
                if (('A' <= ch && ch<='z') ||
                   ( '0' <= ch&& ch <= '9')|| ch == '_' ||
                    ch == '.' || ch == '*' || ch == '#')
                    continue;
                else
                    return false;
            }

            // 不能出现连续的# 和 *
            std::vector<std::string> words;
            StrHelper::splite(bindingkey, ".", words);
            for (int i = 1; i < words.size(); i++)
            {
                if (words[i] == "#" && (words[i - 1] == "#" || words[i - 1] == "*"))
                    return false;
                else if (words[i] == "*" && words[i - 1] == "#")
                    return false;
            }
            return true;
        }

        static bool Route(ExchangeType type, const std::string &routing_key, const std::string &binding_key)
        {
            if (type == ExchangeType::DIRECT)
                return routing_key == binding_key;
            else if (type == ExchangeType::FANOUT)
                return true;
            // 主题交换 匹配的规则是利用动态规划
            // dp[i][j]= rdp[i]==bdp[j]
            // #匹配 左边或者上方或者i-1 j-1满足一项即可

            // 去掉.
            std::vector<std::string> rkeys, bkeys;
            StrHelper::splite(routing_key, ".", rkeys);
            StrHelper::splite(binding_key, ".", bkeys);
            int m = rkeys.size(), n = bkeys.size();
            std::vector<std::vector<bool>> dp(m+1, std::vector<bool>(n+1, false));
            // 初始化
            dp[0][0] = true;
            if (bkeys[0] == "#")
            {
                for (int i = 1; i <=n; i++)
                {
                    dp[0][i] = true;
                }
            }

            for (int i = 1; i <= m; i++)
            {
                for (int j = 1; j <=n; j++)
                {
                    if (rkeys[i - 1] == bkeys[j - 1] || bkeys[j - 1] == "*")
                    {
                        dp[i][j] = dp[i - 1][j - 1];
                    }

                    else if (bkeys[j - 1] == "#")
                    {
                        dp[i][j] = dp[i - 1][j] | dp[i][j - 1] | dp[i - 1][j - 1];
                    }
                }
            }
            return dp[m][n];
        }
    };
}